package cn.zwk.ware.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.zwk.common.constant.WareConstant;
import cn.zwk.common.utils.PageUtils;
import cn.zwk.common.utils.Query;
import cn.zwk.ware.dao.PurchaseDao;
import cn.zwk.ware.entity.PurchaseDetailEntity;
import cn.zwk.ware.entity.PurchaseEntity;
import cn.zwk.ware.entity.PurchaseReasonEntity;
import cn.zwk.ware.service.PurchaseDetailService;
import cn.zwk.ware.service.PurchaseReasonService;
import cn.zwk.ware.service.PurchaseService;
import cn.zwk.ware.service.WareSkuService;
import cn.zwk.ware.vo.MergeVo;
import cn.zwk.ware.vo.PurchaseDoneVo;
import cn.zwk.ware.vo.PurchaseItemDoneVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@Service("purchaseService")
public class PurchaseServiceImpl extends ServiceImpl<PurchaseDao, PurchaseEntity> implements PurchaseService {
    @Autowired
    private PurchaseDetailService detailService;
    @Autowired
    private PurchaseReasonService reasonService;
    @Autowired
    private WareSkuService wareSkuService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<PurchaseEntity> page = this.page(
                new Query<PurchaseEntity>().getPage(params),
                new QueryWrapper<PurchaseEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public PageUtils queryPageUnreceivePurchase(Map<String, Object> params) {
        LambdaQueryWrapper<PurchaseEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.and(w->{
            w.eq(PurchaseEntity::getStatus,0).or().eq(PurchaseEntity::getStatus,1);
        });
        IPage<PurchaseEntity> page = this.page(new Query<PurchaseEntity>().getPage(params), wrapper);
        return new PageUtils(page);
    }

    /**
     * 合并需求
     * @param mergeVo
     */
    @Transactional
    @Override
    public void mergePurchase(MergeVo mergeVo) {
        //1.对提交的需求进行校验（提交的只能是未分配或新建态的）
        LambdaQueryWrapper<PurchaseDetailEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(PurchaseDetailEntity::getPurchaseId,mergeVo.getItems());
        wrapper.not(w->{
            w.eq(PurchaseDetailEntity::getStatus,WareConstant.PurchaseDetailStatusEnum.ASSIGNED.getCode())
                    .or().eq(PurchaseDetailEntity::getStatus,WareConstant.PurchaseDetailStatusEnum.CREATED.getCode());
        });
        if (detailService.count(wrapper)>0){
            throw new RuntimeException("只能合并到新建或已分配的采购单中");
        }
        if (mergeVo.getPurchaseId() ==null) {
            PurchaseEntity purchase=new PurchaseEntity();
            purchase.setStatus(WareConstant.PurchaseStatusEnum.CREATED.getCode());
            this.save(purchase);
            mergeVo.setPurchaseId(purchase.getId());
        }

        List<PurchaseDetailEntity> detailEntityList = mergeVo.getItems().stream().map(item -> {
            PurchaseDetailEntity detailEntity = new PurchaseDetailEntity();
            detailEntity.setId(item);
            detailEntity.setPurchaseId(mergeVo.getPurchaseId());
            detailEntity.setStatus(WareConstant.PurchaseDetailStatusEnum.ASSIGNED.getCode());
            return detailEntity;
        }).collect(Collectors.toList());
        detailService.updateBatchById(detailEntityList);
    }

    /**
     * 领取采购单
     * @param ids
     */
    @Transactional
    @Override
    public void received(List<Long> ids) {
        //1.修改采购单状态
        LambdaUpdateWrapper<PurchaseEntity> wrapper = new LambdaUpdateWrapper<>();
        wrapper.set(PurchaseEntity::getStatus, WareConstant.PurchaseStatusEnum.RECEIVE.getCode());
        wrapper.in(PurchaseEntity::getId,ids)
                .eq(PurchaseEntity::getStatus,WareConstant.PurchaseStatusEnum.ASSIGNED.getCode());
        this.update(wrapper);
        //2.修改采购需求状态
        LambdaUpdateWrapper<PurchaseDetailEntity> detailWrapper = new LambdaUpdateWrapper<>();
        detailWrapper.set(PurchaseDetailEntity::getStatus,WareConstant.PurchaseDetailStatusEnum.BUYING.getCode());
        detailWrapper.eq(PurchaseDetailEntity::getStatus,WareConstant.PurchaseDetailStatusEnum.ASSIGNED.getCode());
        detailWrapper.in(PurchaseDetailEntity::getPurchaseId,ids);
        detailService.update(detailWrapper);
    }

    /**
     * 完成采购单
     * @param doneVo
     */
    @Transactional
    @Override
    public void finish(PurchaseDoneVo doneVo) {
        //1.改变需求状态，并保存错误信息
        List<PurchaseItemDoneVo> items = doneVo.getItems();
        List<PurchaseReasonEntity> reasonList=new ArrayList<>();
        List<PurchaseDetailEntity> detailList=new ArrayList<>();
        for (PurchaseItemDoneVo item : items) {
            PurchaseDetailEntity detailEntity = new PurchaseDetailEntity();
            //采购失败时，存入错误信息,成功时将采购数量添加至仓库
            if (item.getStatus()== WareConstant.PurchaseDetailStatusEnum.HASERROR.getCode()){
                reasonList.add(new PurchaseReasonEntity(item.getItemId(),doneVo.getId(),item.getReason()));
            }else{
                PurchaseDetailEntity entity = detailService.getById(item.getItemId());
                //添加库存
                wareSkuService.addStock(entity.getSkuId(),entity.getWareId(),entity.getSkuNum());
            }
            detailEntity.setId(item.getItemId());
            detailEntity.setStatus(item.getStatus());
            detailEntity.setId(item.getItemId());
            detailList.add(detailEntity);
        }
        detailService.updateBatchById(detailList);
        //2.改变采购单状态
        PurchaseEntity purchaseEntity = new PurchaseEntity();
        purchaseEntity.setId(doneVo.getId());
        purchaseEntity.setStatus(WareConstant.PurchaseStatusEnum.FINISH.getCode());
        //当订单存在错误时
        if (reasonList.size()>0){
            reasonService.saveBatch(reasonList);
            purchaseEntity.setStatus(WareConstant.PurchaseStatusEnum.HASERROR.getCode());
        }
        this.updateById(purchaseEntity);
    }

}
